/**************************************************************************//**
* @file     rpmc.h
* @brief    RPMC library header file
*
* SPDX-License-Identifier: Apache-2.0
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#ifndef __RPMC_H__
#define __RPMC_H__

#include <stdint.h>

#ifdef __cplusplus
extern "C"
{
#endif

#define QSPI_FLASH_PORT  QSPI0

#define AF_REG_STATUS_BUSY           (1<<0)

/* Root Keys Overwrite or Root Keys length mismatch or TruncatedSig Mismatch */
#define AF_REG_STATUS_BIT1           (1<<1)

/* Signature Mismatch or Counter Address out of range or Write_Mode out of range */
#define AF_REG_STATUS_BIT2           (1<<2)

/* HMAC Key Reg Uninitialized */
#define AF_REG_STATUS_BIT3           (1<<3)

/* Monotonic_Counter_Data Mismatch */
#define AF_REG_STATUS_BIT4           (1<<4)

#define AF_REG_STATUS_FATAL_ERROR    (1<<5)
#define AF_REG_STATUS_SUCCESS        (1<<7)

/**
  * @brief Read JEDECID
  * @param[in] Stored data buffer start address.
  * @return None
  */
void RPMC_ReadJEDECID(uint8_t* pu8Data);

/**
  * @brief Read UID
  * @param[in] Stored data buffer start address.
  * @return None
  */
void RPMC_ReadUID(uint8_t* pu8Data);

/**
  * @brief SPI BYTE transfer
  * @param[in] Transferred byte.
  * @return Received byte.
  */
uint8_t RPMC_ByteTransfer(uint8_t DI);

/**
  * @brief Read Monotonic Counter.
  * @param[in] None.
  * @return 32-bit monotonic counter value
  */
uint32_t RPMC_ReadCounter(void);

/**
  * @brief Read status.
  * @param[in] Stored data buffer start address. 0: Read out RPMC status only, 1: Read out counter, tag, signature information.
  * @return RPMC status.
  */
uint32_t RPMC_ReadStatus(uint32_t u32ChkoutFlag);

/**
  * @brief Request counter.
  * @param[in] Selected counter address, from 1~4.
  * @param[in] 32-byte HMACKEY which is generated by RPMC_UpdateHMACKey().
  * @param[in] 12-byte input Tag data, which can be time stamp, serial number or random number.
  * @return RPMC status.
  * @note These return data would repeat after invoking RPMC_RequestCounter() operation.
  */
void RPMC_RequestCounter(uint32_t u32CntAddr, uint8_t* pu8HMACKey, uint8_t* pu8InTag);

/**
  * @brief Write Rootkey.
  * @param[in] Selected counter address, from 1~4.
  * @param[in] 32-byte rootkey information.
  * @return RPMC status.
  * @note Notice, it is an OTP.
  */
uint32_t RPMC_WriteRootKey(uint32_t u32CntAddr, uint8_t* pu8RootKey);

/**
  * @brief Update HMAC Key.
  * @param[in] Selected counter address, from 1~4.
  * @param[in] 32-byte rootkey information.
  * @param[in] 4-byte input hmac message data, which can be time stamp, serial number or random number.
  * @param[in] 32 byte HMACKEY, which would be use for increase/request counter after RPMC_UpdateHMACKey() operation success.
  * @return RPMC status.
  */
uint32_t RPMC_UpdateHMACKey(uint32_t u32CntAddr, uint8_t* pu8RootKey, uint8_t *pu8HMAC, uint8_t * pu8HMACKey);

/**
  * @brief Increase counter.
  * @param[in] Selected counter address, from 1~4.
  * @param[in] 32-byte HMACKEY, which would be use for increase/request counter after RPMC_UpdateHMACKey()
  * @param[in] 12-byte input Tag data, which can be time stamp, serial number or random number.
  * @return RPMC status.
  * @note These returned data would repeat after invoking RPMC_RequestCounter() operation
  */
uint32_t RPMC_IncreaseCounter(uint32_t u32CntAddr, uint8_t *pu8HMACKey, uint8_t* pu8InTag);

/**
  * @brief Challenge signature.
  * @param[in] Selected counter address, from 1~4.
  * @param[in] 32-byte HMACKEY, which would be use for increase/request counter after RPMC_UpdateHMACKey()
  * @param[in] 12-byte input Tag data, which can be time stamp, serial number or random number.
  * @return Challenge result.
  * @retval 0 Signature match.
  * @note These returned data would repeat after invoking RPMC_RequestCounter() operation
  */
int32_t RPMC_Challenge(uint32_t u32CntAddr, uint8_t *pu8HMACKey, uint8_t* pu8InTag);

/**
  * @brief Challenge signature.
  * @param[in] None.
  * @return None.
  */
void RPMC_ResetDevice(void);

/**
  * @brief A create Rootkey reference.
  * @param[in] spi flash UID.
  * @param[in] UID length.
  * @param[out] 32-byte outputted Rootkey buffer.
  * @return None.
  */
void RPMC_CreateRootKey(uint8_t *pu8ID, uint32_t u32IDLen, uint8_t *pu8Rootkey);

#ifdef __cplusplus
}
#endif

#endif //__RPMC_H__
